package liga;

import java.util.*;
import javax.swing.*;
import javax.swing.event.ListDataListener;

interface display{
    void display();
}





class Liga implements display{
    Liga(String l, String n, int k){
        this.Land=l;
        this.name=n;
        this.klasse=k;
    }
    void neueSaison(Saison s){
        saison.add(s);
    }
    
    public Saison getsaison(){
        return saison.element();
    }
    
    String name;
    String Land;
    int klasse;
    static PriorityQueue<Saison> saison = new PriorityQueue();
    
    @Override
    public String toString(){
        return this.name + "(" + this.klasse + ", " + this.Land + ")";
    }
    
    @Override
    public void display(){
        System.out.println("Liga"+"\nName: "+this.name+"\nLand: "+this.Land+"\nKlasse: "+this.klasse);
        System.out.println("------------------------------------------------");
    }

    public void tabelle() {
        //System.out.println("----- Tabelle -----");
        int i=1;
        String text="";
        String text2="";
        for (Mannschaft m : saison.peek().tabelle){
            text = text + i++ + (i>9?". ":".  ")+m.name+"\n";
            text2 = text2 + " " + m.Punkte+"  "+m.Tore+":"+(m.Tore-m.Tore_diff)+"\n";
        //System.out.println(i + ". "+m.name+" "+m.Punkte+" "+m.Tore+":"+(m.Tore-m.Tore_diff));
        }
        liga.gui.jTextPane2.setText(text);
        liga.gui.jTextPane3.setText(text2);
        liga.gui.jTextPane2.setSize(80, saison.peek().teams_Anzahl*20);
        liga.gui.jTextPane3.setSize(50, saison.peek().teams_Anzahl*20);
        liga.gui.jTextPane4.setText(this.name + "\n ( Klasse: " + this.klasse + ", Land: " + this.Land + ")");
    }
}

class Saison implements Comparable<Saison>, display{
        
    int jahr;
    int teams_Anzahl;
    int anzahl_spieltage;
    Mannschaft[] teams;
    PriorityQueue<Mannschaft> tabelle = new PriorityQueue();
    PriorityQueue<Spieltag> spieltage = new PriorityQueue();
    public static Mannschaft leer;
    Random r = new Random(System.currentTimeMillis());
        
    Saison(int j, int a){
        this.teams = new Mannschaft[a%2==0? a : a+1];
        if (a%2!=0) teams[a]= new Mannschaft("leer", r.nextInt(), a);
        this.teams_Anzahl=a;
        this.jahr=j;
        this.anzahl_spieltage=(teams.length-1)*2;
        createTeams(a);
        int i=0;
        for (Mannschaft t : tabelle){
            t.random_nr=i;
            teams[i]=t;
            i++;
        }
        for (int x=0; x<teams.length; x++){
            teams[x].random_nr=x;
        }
        Spielplan();
        
    }
    
    private void createTeams(int a){
        for (int i=0; i<a; i++){
            Mannschaft team = new Mannschaft (JOptionPane.showInputDialog(
                    "Bitte Namen des Teams eingeben"), r.nextInt(), i);
            tabelle.add(team);
        }
    }
       
    @Override
    public int compareTo(Saison other){
        return this.jahr-other.jahr;
    }
   
    private void Spielplan(){
        int x = teams.length/2;
        Mannschaft[][] reihe = new Mannschaft[2][x];
        int i=0;
        
        //Mannschaften in 2 Reihe ordnen
        for (Mannschaft m : teams){
            reihe[i<x? 0 : 1][i<x? i : i-x] = m;
            i++;
        }
        
        //2Spieltage erstellen
        for (int n=1;n<=x;n++){
            Spieltag s1= new Spieltag(2*n-1);
            Spieltag s2= new Spieltag(2*n);
            this.spieltage.add(s1);
            if ((2*n)<teams.length) this.spieltage.add(s2);
            
            //2 Spieltage füllen
            for (int j=0; j<x; j++){
                Spiel spiel = new Spiel(true);  
                spiel.m1=reihe[0][j];
                spiel.m2=reihe[1][j];
                spiel.wertung=spiel.m1.real && spiel.m2.real;
                s1.spiele.add(spiel);
                Spiel spiel2 = new Spiel(true);  
                spiel2.m2=reihe[0][j];
                spiel2.m1=reihe[1][j+1==x? 0 : j+1];
                spiel2.wertung=spiel2.m1.real && spiel2.m2.real;
                s2.spiele.add(spiel2);
            }
            
            //Mannschaften in den 2 Reihen um 1 Position verschieben
            Mannschaft[][] reihe2 = new Mannschaft[2][x];
            for (int j=0; j<x; j++){
                reihe2[0][j]= j==0? reihe[1][0] : reihe[0][j-1]; 
                reihe2[1][j]= j==x-1? reihe[0][j] : reihe[1][j+1];
            }
            for (int j=0; j<x; j++){
                reihe[0][j]= reihe2[0][j];
                reihe[1][j]= reihe2[1][j];
            }
        }
        
        
        //Rückrunde
        ArrayList<Spieltag> temp = new ArrayList();
        for (Spieltag st : this.spieltage){
            Spieltag stag = new Spieltag(st.nr+teams.length-1);
            temp.add(stag);
            for (Spiel sp : st.spiele){
                Spiel s = new Spiel(sp.m1.real && sp.m2.real);
                s.m1=sp.m2;
                s.m2=sp.m1;
                stag.spiele.add(s);
            }
        }
        for (Spieltag s : temp) {this.spieltage.add(s);}
    }
    
        
    @Override
    public void display(){
        System.out.println("Saison: " + (this.jahr-1) + "-" + this.jahr);
        System.out.println("teilnehmende Mannschaften:");
        for (Mannschaft m : this.tabelle){
            if (m.real) System.out.println(" - "+m.name);
        }
        System.out.println("------------------------------------------------");
    } 
}

class Mannschaft implements Comparable<Mannschaft>{
    Mannschaft (String n, int rnd, int i){
        this.real = n.equals("leer")? false : true;
        this.name=n;
        this.random_nr=rnd;
        this.Punkte=0;
        this.Tore=0;
        this.Tore_diff=0;
        this.Spiele=0;
    }
    
    String name;
    int Punkte;
    int Spiele;
    int Tore;
    int Tore_diff;
    int random_nr;
    boolean b=false;
    boolean real;
    
    @Override
    public int compareTo(Mannschaft other){
        if (this.Punkte<other.Punkte) return -1;
        if (this.Punkte>other.Punkte) return 1;
        if (this.Tore_diff<other.Tore_diff) return -1;
        if (this.Tore_diff>other.Tore_diff) return 1;
        if (this.Tore<other.Tore) return -1;
        if (this.Tore>other.Tore) return 1;
        return this.random_nr-other.random_nr;
    }
}

class Spieltag implements Comparable<Spieltag>, display{
    Spieltag(int x){
        this.nr=x;
    }
    int nr;
    @Override
    public int compareTo(Spieltag other){
        return this.nr-other.nr;
    }
    ArrayList<Spiel> spiele = new ArrayList();
    
        @Override
    public String toString(){
        return "Spieltag " + this.nr;
    }
        
    public String spieletoString(){
        String st = "";
        for (Spiel s : spiele){
            if (s.wertung) st = st + s.m1.name+" "+
                        (s.gespielt? s.Tore_m1 + ":" + s.Tore_m2 : "-")+
                        " "+s.m2.name + "\n";
            else st = st + "spielfrei: " + (s.m1.real? s.m1.name : s.m2.name) + "\n";
        }
        return st.length()>0? st : "keine Spiele";
    }
    
    @Override
    public void display(){
        System.out.println("----- Spieltag "+this.nr+" -----");
        for (Spiel s : spiele){
            if (s.wertung)
                System.out.println(s.m1.name+" "+
                        (s.gespielt? s.Tore_m1 + ":" + s.Tore_m2 + " " : "-")+
                        " "+s.m2.name);
            else System.out.println("spielfrei: " + (s.m1.real? s.m1.name : s.m2.name));
        }
        System.out.println("------------------------------------------------");
    }
}

class Spiel{
    Spiel(boolean w){
        this.wertung=w;
    }
    Mannschaft m1;
    Mannschaft m2;
    int Tore_m1;
    int Tore_m2;
    boolean wertung=true;
    boolean gespielt=false;
    
    @Override
    public String toString(){
        String st="";
        if (wertung) st = m1.name+" "+
                        (gespielt? Tore_m1 + ":" + Tore_m2 : "-")+
                        " "+m2.name + "\n";
        else st = "spielfrei: " + (m1.real? m1.name : m2.name) + "\n";
        return st;
    }
}

public class RenesLiga {
    
    /**TODO
     *  save()
     *  load()
     *  Ergebnisse eintragen() ändern()
     */
    
    
    public static void main(String[] args) {
        liga.gui.main(args);
    }
}
